package cn.com.yd.commons.grpc.util;

import com.alibaba.fastjson.JSONObject;
import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.runtime.RuntimeSchema;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Protobuf工具类
 * 
 * @author 李庆海
 *
 */
public class ProtobufUtils {

	/** 缓存 schema 对象的 map */
	private static Map<Class<?>, RuntimeSchema<?>> cachedSchema = null;
	static {
		cachedSchema = new ConcurrentHashMap<>();
		/** 预先缓存JSONObject */
		cachedSchema.put(JSONObject.class, RuntimeSchema.createFrom(JSONObject.class));
	}

	/**
	 * 根据获取相应类型的schema方法
	 */
	@SuppressWarnings({ "unchecked", "unused" })
	private static <T> RuntimeSchema<T> getSchema(Class<T> clazz) {
		RuntimeSchema<T> schema = (RuntimeSchema<T>) cachedSchema.get(clazz);
		if (schema == null) {
			schema = RuntimeSchema.createFrom(clazz);
			cachedSchema.put(clazz, schema);
		}
		return schema;
	}

	/**
	 * 序列化方法，将对象序列化为字节数组（对象 ---> 字节数组）
	 */
	@SuppressWarnings("unchecked")
	public static <T> byte[] serialize(T obj) {
		Class<T> clazz = (Class<T>) obj.getClass();
		RuntimeSchema<T> schema = getSchema(clazz);
		LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
		return ProtostuffIOUtil.toByteArray(obj, schema, buffer);
	}

	/**
	 * 反序列化方法，将字节数组反序列化为对象（字节数组 ---> 对象）
	 */
	public static <T> T deserialize(byte[] data, Class<T> clazz) {
		RuntimeSchema<T> schema = RuntimeSchema.createFrom(clazz);
		T message = schema.newMessage();
		ProtostuffIOUtil.mergeFrom(data, message, schema);
		return message;
	}
}
